
/* -*-C-*-
 ##############################################################################
 #
 # File:        trice/src/misc.c
 # RCS:         "@(#)$Revision: 1.13 $ $Date: 94/03/09 11:10:48 $"
 # Description: misc routines needed by both user callable routines and
 #		SCPI routines
 # Author:      Doug Passey
 # Created:     
 # Language:    C
 # Package:     E1430
 # Status:      "@(#)$State: Exp $"
 #
 # (C) Copyright 1992, Hewlett-Packard Company, all rights reserved.
 #
 ##############################################################################
 #
 # Please add additional comments here
 #
 # Revisions:
 #
 ##############################################################################
*/

#    include <stdio.h>

#define NO_EXTERN_FLAG			/* allocate globals in this module */

#include "trice.h"
#include "err1430.h"

#ifndef lint
const char misc_fileId[] = "$Header: misc.c,v 1.13 94/03/09 11:10:48 chriss Exp $";
#endif


/*****************************************************************************
 *
 * Returns size of one sample of data in FIFO from parameters in the 
 * Data Format Register.  
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_fifo_data_point_size(SHORTSIZ16 la, SHORTSIZ16 *size)
{
  SHORTSIZ16 index;
  SHORTSIZ16 dataFormat;
  SHORTSIZ16 error;
  SHORTSIZ16 multipass;
  SHORTSIZ16 numBytes;

  error = i1430_get_index_from_la(la, &index);
  if(error) return(error);

  dataFormat = e1430_modStates[index].dataFormat;
  
  multipass = (dataFormat & ~DATA_FORMAT_FILTER_MULTIPASS_MASK) == 
					DATA_FORMAT_FILTER_MULTIPASS;

  switch(dataFormat & ~DATA_FORMAT_DATA_TYPE_MASK) {
    case DATA_FORMAT_DATA_TYPE_REAL:
      switch(dataFormat & ~DATA_FORMAT_DATA_SIZE_MASK) {
	case DATA_FORMAT_DATA_SIZE_16:
	  numBytes = 2;
	  if(multipass) numBytes *= 2;		/* extra 16 bits appended */
	  break;
	case DATA_FORMAT_DATA_SIZE_32:
	  numBytes = 4;
	  break;
	default:
	  return(i1430_Error(ERR1430_ILLEGAL_DATA_SIZE, NULL, NULL));
      }
      *size = numBytes;
      return (0);

    case DATA_FORMAT_DATA_TYPE_COMPLEX:
      switch(dataFormat & ~DATA_FORMAT_DATA_SIZE_MASK) {
	case DATA_FORMAT_DATA_SIZE_16:
	  numBytes = 4;
	  break;
	case DATA_FORMAT_DATA_SIZE_32:
	  numBytes = 8;
	  break;
	default:
	  return(i1430_Error(ERR1430_ILLEGAL_DATA_SIZE, NULL, NULL));
      }
      *size = numBytes;
      return (0);

    default:
      return(i1430_Error(ERR1430_ILLEGAL_DATA_TYPE, NULL, NULL));
  }
  
}


/*****************************************************************************
 *
 * Returns size of one sample of data in FIFO for a group of modules
 * from parameters in the Data Format Register.  If they are not all equal
 * an error is returned
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_group_data_pt_size(SHORTSIZ16 groupID, SHORTSIZ16 *size)
{
  SHORTSIZ16 pointSize, s;
  aModGroupPtr ptr;
  SHORTSIZ16 error;

  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  error = e1430_get_fifo_data_point_size(e1430_modStates[*ptr].logicalAddr, 
							&pointSize);
  if(error) return(error);

  ptr++;

  for(; *ptr != -1; ptr++) {		/* check size in all modules */
    error = e1430_get_fifo_data_point_size(e1430_modStates[*ptr].logicalAddr, &s);
    if(error) return(error);

    if(s != pointSize) {
      return(i1430_Error(ERR1430_PARAMETER_UNEQUAL, NULL, NULL));
    }
  }

  *size = pointSize;
  return(0);
}


/*****************************************************************************
 *
 * Returns size of one block of data in FIFO from parameters in the 
 * Data Format Register.  
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_fifo_block_data_size(SHORTSIZ16 la, LONGSIZ32 *size)
{
  SHORTSIZ16 index;
  SHORTSIZ16 pointSize;
  LONGSIZ32 blocksize;
  SHORTSIZ16 error;

  error = e1430_get_fifo_data_point_size(la, &pointSize);
  if(error) return(error);

  error = i1430_get_index_from_la(la, &index);
  if(error) return(error);

  blocksize = i1430_get_blocksize_index(index);
  *size = (LONGSIZ32)pointSize * blocksize;

  return (0);
}

/*****************************************************************************
 *
 * Returns total size of all blocks of data in the FIFOs in modules in
 * <groupID> from parameters in the Data Format Register.  
 *
 ****************************************************************************/
SHORTSIZ16 e1430_total_data_size(SHORTSIZ16 groupID, LONGSIZ32 *size)
{
  aModGroupPtr ptr;
  SHORTSIZ16 error;
  LONGSIZ32 temp;

  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  error = e1430_get_fifo_block_data_size(e1430_modStates[*ptr].logicalAddr, size);
  if(error) return(error);
  
  ptr++;

  for(; *ptr != -1; ptr++) {		/* check size in all modules */
    error = e1430_get_fifo_block_data_size(e1430_modStates[*ptr].logicalAddr, &temp);
    if(error) return(error);
    *size += temp;
  }
  return(0);
} 


/*****************************************************************************
 * Returns size of FIFO in bytes given the logical address of module.
 ****************************************************************************/
SHORTSIZ16 e1430_get_fifo_size(SHORTSIZ16 la, LONGSIZ32 *size)
{
  SHORTSIZ16 error;
  SHORTSIZ16 memBits;

  error = e1430_get_status(la, &memBits);
  if(error) return(error);

  memBits = (memBits & E1430_MEAS_STATUS_MEM_MASK) >> MEMORY_BIT_SHIFT;

  /* return actual size in bytes: 8Mbytes * 2^memBits */
  *size = 0x800000L << memBits;

  return (0);
}

/*****************************************************************************
 *
 * Returns the minimum memory available of all the modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_fifo_max_memory(SHORTSIZ16 groupID, LONGSIZ32 *size)
{
  aModGroupPtr ptr;
  LONGSIZ32 memSize, maxMemSize;
  SHORTSIZ16 error;

  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  maxMemSize = 0L;
  for(; *ptr != -1; ptr++) {		/* get max memory in all modules */
    error = e1430_get_fifo_size(e1430_modStates[*ptr].logicalAddr, &memSize);
    if(error) return(error);

    if(memSize > maxMemSize) {
      maxMemSize = memSize;
    }
  }
  
  *size = maxMemSize;
  return (0);
}

/*****************************************************************************
 *
 * Returns the blocksize available of all the modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_fifo_max_blocksize(SHORTSIZ16 groupID, LONGSIZ32 *size)
{
  aModGroupPtr ptr;
  LONGSIZ32 memSize, maxMemSize;
  SHORTSIZ16 pointSize;
  SHORTSIZ16 error;
  SHORTSIZ16 la;

  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  maxMemSize = 0x7FFFFFFFL;
  for(; *ptr != -1; ptr++) {		/* get min memory in all modules */
    la = e1430_modStates[*ptr].logicalAddr;
    error = e1430_get_fifo_size(la, &memSize);
    if(error) return(error);
    
    error = e1430_get_fifo_data_point_size(la, &pointSize);
    if(error) return(error);

    memSize /= (LONGSIZ32)pointSize;

    if(memSize < maxMemSize) {
      maxMemSize = memSize;
    }
  }
  
  *size = maxMemSize;
  return (0);
}

/*****************************************************************************
 *
 * Returns a SHORTSIZ16 parameter specified by the routine <func> into the 
 * variable pointed to by <parmPtr>.  This parameter must be the same for 
 * all modules * of the module group, <groupID>, or it returns 
 * ERR1430_PARAMETER_UNEQUAL. 
 * If parameter is OK, returns 0;
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_short_parm(SHORTSIZ16 groupID, SHORTSIZ16 (*func)(SHORTSIZ16), 
				char *errorStr, SHORTSIZ16 *parmPtr)
{
  aModGroupPtr ptr;
  SHORTSIZ16 parm, first;
  char buf[80];

  if(NULL == (ptr = i1430_valid_module_group(groupID))) {
    return (ERR1430_NO_GROUP);
  }

  first = (SHORTSIZ16)(*func)(*ptr);
  for(; *ptr != -1; ptr++) {	/* look at parm for all modules */
    parm = (SHORTSIZ16)(*func)(*ptr);
    if(parm != first) {
    (void)sprintf(buf, "%d", (LONGSIZ32)groupID);
      return (i1430_Error(ERR1430_PARAMETER_UNEQUAL, errorStr, buf));
    }
  }

  *parmPtr = parm;
  return (0);
}
 

/*****************************************************************************
 *
 * Returns a LONGSIZ32 parameter specified by the routine <func> into the 
 * variable pointed to by <parmPtr>.  This parameter must be the same for 
 * all modules * of the module group, <groupID>, or it returns 
 * ERR1430_PARAMETER_UNEQUAL. 
 * If parameter is OK, returns 0;
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_long_parm(SHORTSIZ16 groupID, LONGSIZ32 (*func)(SHORTSIZ16), 
				char *errorStr, LONGSIZ32 *parmPtr)
{
  aModGroupPtr ptr;
  LONGSIZ32 parm, first;
  char buf[80];

  if(NULL == (ptr = i1430_valid_module_group(groupID))) {
    return (ERR1430_NO_GROUP);
  }

  first = (LONGSIZ32)(*func)(*ptr);
  for(; *ptr != -1; ptr++) {	/* look at parm for all modules */
    parm = (LONGSIZ32)(*func)(*ptr);
    if(parm != first) {
    (void)sprintf(buf, "%d", (LONGSIZ32)groupID);
      return (i1430_Error(ERR1430_PARAMETER_UNEQUAL, errorStr, buf));
    }
  }

  *parmPtr = parm;
  return (0);
}
 

/*****************************************************************************
 *
 * Returns a FLOATSIZ64 parameter specified by the routine <func> into the 
 * variable pointed to by <parmPtr>.  This parameter must be the same for 
 * all modules * of the module group, <groupID>, or it returns 
 * ERR1430_PARAMETER_UNEQUAL. 
 * If parameter is OK, returns 0;
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_float_parm(SHORTSIZ16 groupID, FLOATSIZ64 (*func)(SHORTSIZ16), 
				char *errorStr, FLOATSIZ64 *parmPtr)
{
  aModGroupPtr ptr;
  FLOATSIZ64 parm, first;
  char buf[80];

  if(NULL == (ptr = i1430_valid_module_group(groupID))) {
    return (ERR1430_NO_GROUP);
  }

  first = (FLOATSIZ64)(*func)(*ptr);
  for(; *ptr != -1; ptr++) {	/* look at parm for all modules */
    parm = (FLOATSIZ64)(*func)(*ptr);
    if(parm != first) {
      (void)sprintf(buf, "%d", (LONGSIZ32)groupID);
      return (i1430_Error(ERR1430_PARAMETER_UNEQUAL, errorStr, buf));
    }
  }

  *parmPtr = parm;
  return (0);
}
 

/*****************************************************************************
 *
 * Returns current value of e1430_timeout
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_timeout(LONGSIZ32 *timeout)
{
  *timeout = e1430_timeout;
  return 0;
}

/*****************************************************************************
 *
 * Sets value of e1430_timeout
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_timeout(LONGSIZ32 setTime)
{ 
  e1430_timeout = setTime;
  return 0;
}


